package com.yyx.jupiter.service.recommend;

import com.alibaba.fastjson2.JSONObject;
import com.yyx.jupiter.conf.PropertyConfig;
import com.yyx.jupiter.entity.RecomReq;
import com.yyx.jupiter.entity.RecomResp;
import com.yyx.jupiter.entity.RecomVideo;
import com.yyx.jupiter.service.recommend.rank.HobbyRank;
import com.yyx.jupiter.service.recommend.recall.RecallManager;
import com.yyx.jupiter.service.recommend.rerank.RerankManager;
import com.yyx.jupiter.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.context.config.annotation.RefreshScope;

import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

@Slf4j
@Service
@RefreshScope
public class HomeRecommendService implements RecommendService<RecomVideo> {

    @Resource
    PropertyConfig propertyConfig;

    @Resource
    private RecallManager recallManager;

    @Resource
    private RerankManager rerankManager;

    @Resource(name = "pool")
    private ExecutorService executorService;

    @Resource
    private HobbyRank hobbyRank;

    @Override
    public RecomResp<RecomVideo> recommend(RecomReq recomReq) throws Exception {
        String requestId = recomReq.getRequestId();
        String strategy = recomReq.getStrategy();

        log.info("RecomReq: {}", JsonUtils.toJsonString(recomReq));

        // 读取配置
        JSONObject strategyJson = propertyConfig.getStrategy().getJSONObject(strategy);

        // 初始化返回体
        RecomResp<RecomVideo> recomResp = new RecomResp<>();
        recomResp.setRequestId(requestId);

        // 多路召回
        List<RecomVideo> recomItems = recallManager.getRecallVideos(recomReq, executorService);

        // 召回截断
        int recallLimitNum = strategyJson.getInteger("recallLimitNum");
        recomItems = recomItems.stream().limit(recallLimitNum).collect(Collectors.toList());
        if (recomItems.isEmpty()) {
            log.error("请求{}获取不到召回", recomReq);
            return recomResp;
        }

        // 塞入正排数据
        recomItems = recallManager.fillRecomVideoData(recomItems);

        // 过滤下架物品
        recomItems = recallManager.filterRemovedVideos(recomItems);
        if (recomItems.isEmpty()) {
            log.error("请求{}过滤下架物品后无召回", recomReq);
            return recomResp;
        }

        // 排序
        recomItems = hobbyRank.rank(recomItems, recomReq);

        // 重排
        recomItems = rerankManager.getRerankItemList(recomReq, recomItems);

        // 组装返回体
        recomResp.setRecomList(recomItems);

        return recomResp;
    }
}
